package com.lst.projectlib.component.CustomView;

import java.util.Timer;
import java.util.TimerTask;

import com.lst.projectlib.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;


public class CircleProgress extends View{

	
	 public OnSeekChangeListener getmListener() {
		return mListener;
	}


	public void setmListener(OnSeekChangeListener mListener) {
		this.mListener = mListener;
	}

	private  static final int DEFAULT_MAX_VALUE = 100;					// 默认进度条最大值
	 private  static final int DEFAULT_PAINT_WIDTH = 10;				// 默认画笔宽度
	 private  static final int DEFAULT_PAINT_COLOR = 0xffffcc00;		// 默认画笔颜色
	 private  static final boolean DEFAULT_FILL_MODE = true;			// 默认填充模式
	 private  static final int DEFAULT_INSIDE_VALUE = 0;				// 默认缩进距离
	
	 private CircleAttribute mCircleAttribute;			// 圆形进度条基本属性

	 private float mMaxProgress;							// 进度条最大值	 	 																												
	 private float mMainCurProgress;						// 主进度条当前值 
	 private float mEndProgress;							// 进度条最后显示的值	 	
	
	 private CartoomEngine mCartoomEngine;				// 动画引擎
	
	 private Drawable mBackgroundPicture;				// 背景图
	 
	 private boolean mIsAllowTouch = false;             // 是否允许触摸改变进度
		
	 
	 public CircleProgress(Context context)
	 {
			super(context);		
			defaultParam();
	}

	 
	public CircleProgress(Context context, AttributeSet attrs) {
		super(context, attrs);
             
		defaultParam();
		
		
		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);      
	        
	    mMaxProgress = DEFAULT_MAX_VALUE; 				// 获取进度条最大值	
	    mEndProgress = DEFAULT_MAX_VALUE;               // 进度条最后显示的值	 	
	    
	    boolean bFill = array.getBoolean(R.styleable.CircleProgressBar_fill, DEFAULT_FILL_MODE);			// 获取填充模式
	    int paintWidth = array.getInt(R.styleable.CircleProgressBar_Paint_Width, DEFAULT_PAINT_WIDTH);		// 获取画笔宽度	    
        mCircleAttribute.setFill(bFill);
        if (bFill == false)
        {
        	mCircleAttribute.setPaintWidth(paintWidth);
        }
        
        int paintColor = array.getColor(R.styleable.CircleProgressBar_Paint_Color, DEFAULT_PAINT_COLOR);	 // 获取画笔颜色
        mCircleAttribute.setPaintColor(paintColor);
        
        int subPaintColor = array.getColor(R.styleable.CircleProgressBar_Sub_Paint_Color, DEFAULT_PAINT_COLOR);	 // 获取子画笔颜色
        mCircleAttribute.setSubPaintColor(subPaintColor);
        
        int backColor = array.getColor(R.styleable.CircleProgressBar_Back_Color, Color.GRAY);	 // 没有背景图时候的默认底色
        mCircleAttribute.setBackColor(backColor);
        
	    mCircleAttribute.mSidePaintInterval = array.getInt(R.styleable.CircleProgressBar_Inside_Interval, DEFAULT_INSIDE_VALUE);// 圆环缩进距离

	    array.recycle(); //一定要调用，否则会有问题
		
	}

	/*
	 * 默认参数
	 */
	private void defaultParam()
	{
		mCircleAttribute = new CircleAttribute();
		 
		mCartoomEngine = new CartoomEngine();
		
		mMaxProgress = DEFAULT_MAX_VALUE;	
		mEndProgress = DEFAULT_MAX_VALUE;
		mMainCurProgress = 0;						
	}
	 
	 
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {		// 设置视图大小
		
		int width = MeasureSpec.getSize(widthMeasureSpec);
//		int height = MeasureSpec.getSize(heightMeasureSpec);
		
		mBackgroundPicture = getBackground();
		if (mBackgroundPicture != null)
		{
			width = mBackgroundPicture.getMinimumWidth();
//			height = mBackgroundPicture.getMinimumHeight();
		}
		
		setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(width, heightMeasureSpec));
	}
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		
		mCircleAttribute.autoFix(w, h);
		
		//中心点
		cx=mCircleAttribute.mRoundOval.centerX();
		cy=mCircleAttribute.mRoundOval.centerY();
			
	}
	
	
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		       	
		// 没背景图的话就绘制底色
		if (mBackgroundPicture == null)
		{
			canvas.drawArc(mCircleAttribute.mRoundOval, 0, 360, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mBottomPaint);
		}
		
		// 画主笔
		float rate = (float)(mMainCurProgress < mEndProgress ? mMainCurProgress : mEndProgress) / mMaxProgress;
		float sweep = 360 * rate;
		canvas.drawArc(mCircleAttribute.mRoundOval, mCircleAttribute.mDrawPos, sweep, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mMainPaints);
	
		// 画子笔
		float subRate = (float)(mMainCurProgress > mEndProgress ? (mMainCurProgress - mEndProgress) : 0) / mMaxProgress;
		float subSweep = 360 * subRate;
		canvas.drawArc(mCircleAttribute.mRoundOval, mCircleAttribute.mDrawPos + sweep, subSweep, mCircleAttribute.mBRoundPaintsFill, mCircleAttribute.mSubPaint);
	}
	
	
	/*
	 * 设置主进度值
	 */
	 public synchronized void setMainProgress (float progress)
	 {
	    	mMainCurProgress = progress;
	    	if (mMainCurProgress < 0)
	    	{
	    		mMainCurProgress = 0;
	    	}
	    	
	    	if (mMainCurProgress > mMaxProgress)
	    	{
	    		mMainCurProgress = mMaxProgress;
	    	}
	    	
	    	invalidate();
	}
	    
    public synchronized float getMainProgress()
    {
    	return mMainCurProgress;
    }
    
    /*
     * 开启动画
     */
	public  void  startCartoom(int time)
	{
		mCartoomEngine.startCartoom(time);

	}
	
	/*
	 * 结束动画
	 */
	public  void  clearCartoom()
	{
		mCartoomEngine.clearCartoom();
	}
	
	
	
	class CircleAttribute
	{
		 public RectF  	mRoundOval;					// 圆形所在矩形区域
		 public boolean mBRoundPaintsFill;			// 是否填充以填充模式绘制圆形
		 public int  	mSidePaintInterval;			// 圆形向里缩进的距离
		 public int    	mPaintWidth;				// 圆形画笔宽度（填充模式下无视）
		 public int     mPaintColor;				// 画笔颜色  （即主进度条画笔颜色，子进度条画笔颜色为其半透明值） 
		 public int     mBackColor;				    // 没有背景图时候的默认底色
		 public int     mDrawPos;					// 绘制圆形的起点（默认为-90度即12点钟方向）
		 
		 public Paint   mMainPaints;				// 主进度条画笔 	    
		 public Paint   mSubPaint;    				// 子进度条画笔 
		 
		 public Paint   mBottomPaint;				// 无背景图时绘制所用画笔

		 
		 public CircleAttribute()
		 {
			mRoundOval = new RectF();
			mBRoundPaintsFill = DEFAULT_FILL_MODE;
			mSidePaintInterval = DEFAULT_INSIDE_VALUE;
			mPaintWidth = 0;
			mPaintColor = DEFAULT_PAINT_COLOR;
			mBackColor = Color.GRAY;
			mDrawPos = -90;
			 
			mMainPaints = new Paint();		
			mMainPaints.setAntiAlias(true);
			mMainPaints.setStyle(Paint.Style.FILL);
			mMainPaints.setStrokeWidth(mPaintWidth);
			mMainPaints.setColor(mPaintColor);
		     
			mSubPaint = new Paint();
			mSubPaint.setAntiAlias(true);
			mSubPaint.setStyle(Paint.Style.FILL);
			mSubPaint.setStrokeWidth(mPaintWidth);
			mSubPaint.setColor(mPaintColor);
				
			mBottomPaint = new Paint();
			mBottomPaint.setAntiAlias(true);
			mBottomPaint.setStyle(Paint.Style.FILL);
			mBottomPaint.setStrokeWidth(mPaintWidth);
			mBottomPaint.setColor(mBackColor);
		 }
	
		 
		 /*
		  * 设置画笔宽度
		  */
		 public void setPaintWidth(int width)
		 {
			 mMainPaints.setStrokeWidth(width);
			 mSubPaint.setStrokeWidth(width);
			 mBottomPaint.setStrokeWidth(width);
		 }
		 
		 /*
		  * 设置画笔颜色
		  */
		 public void setPaintColor(int color)
		 {
			 mMainPaints.setColor(color);
		 }
		 
		 /*
		  * 设置子画笔颜色
		  */
		 public void setSubPaintColor(int color)
		 {
		     mSubPaint.setColor(color);
		 }
		 
		 /*
		  * 设置默认背景颜色
		  */
		 public void setBackColor(int color)
		 {
			 mBottomPaint.setColor(color);
		 }
		 
		 /*
		  * 设置填充模式
		  */
		 public void setFill(boolean fill)
		 {
			 mBRoundPaintsFill = fill;
			 if (fill)
			 {
				 mMainPaints.setStyle(Paint.Style.FILL);
				 mSubPaint.setStyle(Paint.Style.FILL);	 
				 mBottomPaint.setStyle(Paint.Style.FILL);	
			 }else{
				 mMainPaints.setStyle(Paint.Style.STROKE);
				 mSubPaint.setStyle(Paint.Style.STROKE);	
				 mBottomPaint.setStyle(Paint.Style.STROKE);	
			 }	
		 }
		 
		/*
		 * 自动修正
		 */
		 public void autoFix(int w, int h)
		 {
			if (mSidePaintInterval != 0)
			{
				mRoundOval.set(mPaintWidth/2 + mSidePaintInterval, mPaintWidth/2 + mSidePaintInterval,
				w - mPaintWidth/2 - mSidePaintInterval, h - mPaintWidth/2 - mSidePaintInterval);	
			}else{

				int sl = getPaddingLeft();
				int sr = getPaddingRight();
				int st = getPaddingTop();
				int sb = getPaddingBottom();
			
						
				mRoundOval.set(sl + mPaintWidth/2, st + mPaintWidth/2, w - sr - mPaintWidth/2, h - sb - mPaintWidth/2);	
			}	
		 }
			
	}
	
	class CartoomEngine
	{
		public Handler mHandler; 
		public boolean mBCartoom;					// 是否正在作动画 
		public Timer   mTimer;						// 用于作动画的TIMER 
		public		 MyTimerTask	mTimerTask;			// 动画任务
		public float 	 mSaveMax;						// 在作动画时会临时改变MAX值，该变量用于保存值以便恢复	 
		public float 	 mSaveEnd;						// 在作动画时会临时改变End值，该变量用于保存值以便恢复	 
		public int     mTimerInterval;				// 定时器触发间隔时间(ms)	 
		public float   mCurFloatProcess;			// 作动画时当前进度值 

		public CartoomEngine()
		{
			mHandler = new Handler(new Handler.Callback() {
				
				@Override
				public boolean handleMessage(Message msg) {
					switch(msg.what)
					{
						case TIMER_ID:
						{
							if (mBCartoom == false)
							{
								return false;
							}
							
						
							mCurFloatProcess += 1;
							setMainProgress(mCurFloatProcess);
							
							if (mCurFloatProcess >= mMaxProgress)
							{
								stopCartoom();
							}
						}
						break;
					}
					return false;
				}
			});
			
			mBCartoom = false;
			mTimer = new Timer();
			mSaveMax = 0;
			mSaveEnd = 0;
			mTimerInterval = 50;
			mCurFloatProcess = 0;
		}
		
		public synchronized void  startCartoom(int time)
		{
			if (time <= 0 || mBCartoom == true)
			{
				return ;
			}
			
			mBCartoom = true;

			setMainProgress(0);
			
			mSaveMax = mMaxProgress;
			mSaveEnd = mEndProgress;
			
			// 暂时改变最大值，使其为动画时间的比例
			mMaxProgress = ((float)1000 / mTimerInterval) * time;
			mEndProgress = (mSaveEnd / mSaveMax) * mMaxProgress;
			mCurFloatProcess = 0;
		
			
			mTimerTask = new MyTimerTask();
			mTimer.schedule(mTimerTask, mTimerInterval, mTimerInterval);
		}
		
		public synchronized void  stopCartoom()
		{
			mBCartoom = false;
			mMaxProgress = mSaveMax;
			mEndProgress = mSaveEnd;
			
			setMainProgress(mMaxProgress);
			
			if (mTimerTask != null)
			{
				mTimerTask.cancel();
				mTimerTask = null;
			}
			
			if (mListener != null) {
				mListener.onStopProgressChangeCartoom();
			}
		}
		
		public synchronized void  clearCartoom()
		{
			mBCartoom = false;
			mMaxProgress = mSaveMax;
			mEndProgress = mSaveEnd;
			
			setMainProgress(0);
			
			if (mTimerTask != null)
			{
				mTimerTask.cancel();
				mTimerTask = null;
			}
		}
		
		private final static int TIMER_ID = 0x0010;
		
		class MyTimerTask extends TimerTask{

			@Override
			public void run() {
				Message msg = mHandler.obtainMessage(TIMER_ID);
				msg.sendToTarget();
			}
		}
	}
	
	/**
	 * 设置监听器
	 */
	
	/** The circle's center X coordinate */
	private float cx;

	/** The circle's center Y coordinate */
	private float cy;

	/** The flag to see if view is pressed */
	private boolean IS_PRESSED = false;
	
	/** The flag to see if view is user operate */
	private boolean IS_USEROP = false;
	
	/**
	 * The X coordinate for the current position of the marker, pre adjustment
	 * to center
	 */
	private float markPointX;

	/**
	 * The Y coordinate for the current position of the marker, pre adjustment
	 * to center
	 */
	private float markPointY;
	
	/** The angle of progress */
	private float angle = 0;
	
	/** The progress percent */
	private float progressPercent;
	
	/**
	 * The flag to see if the setProgress() method was called from our own
	 * View's setAngle() method, or externally by a user.
	 */
	private boolean CALLED_FROM_ANGLE = false;
	
	
	/**
	 * The listener interface for receiving onSeekChange events. The class that
	 * is interested in processing a onSeekChange event implements this
	 * interface, and the object created with that class is registered with a
	 * component using the component's
	 * <code>setSeekBarChangeListener(OnSeekChangeListener)<code> method. When
	 * the onSeekChange event occurs, that object's appropriate
	 * method is invoked.
	 * 
	 * @see OnSeekChangeEvent
	 */
	public interface OnSeekChangeListener {

		/**
		 * On progress change.
		 * 
		 * @param view
		 *            the view
		 * @param newProgress
		 *            the new progress
		 */
		public void onProgressChange(CircleProgress view, float newProgress, boolean userOp);
		
		/**
		 * 动画结束的回调
		 */
		public void onStopProgressChangeCartoom();
	}
	
	/** The listener to listen for changes */
	private OnSeekChangeListener mListener;
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (!mIsAllowTouch) {
			return super.onTouchEvent(event);
		}
		
		float x = event.getX();
		float y = event.getY();
		boolean up = false;
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			moved(x, y, up);
			break;
		case MotionEvent.ACTION_MOVE:
			moved(x, y, up);
			break;
		case MotionEvent.ACTION_UP:
			up = true;
			moved(x, y, up);
			break;
		}
		return true;
	}
	
	/**
	 * Moved.
	 * 
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 * @param up
	 *            the up
	 */
	private void moved(float x, float y, boolean up) {
		float distance = (float) Math.sqrt(Math.pow((x - cx), 2) + Math.pow((y - cy), 2));
//		if (distance < outerRadius && distance > innerRadius && !up) {
		if (!up) {
			IS_PRESSED = true;
			IS_USEROP=true;

			markPointX = x;
			markPointY = y;

			float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(x - cx, cy - y)) + 360.0)) % 360.0);
			// and to make it count 0-360
			if (degrees < 0) {
				degrees += 2 * Math.PI;
			}

			setAngle(degrees);
			invalidate();

		} else {
			IS_PRESSED = false;
			invalidate();
		}

	}
	/**
	 * Set the angle.
	 * 
	 * @param angle
	 *            the new angle
	 */
	public void setAngle(float angle) {
		this.angle = angle;
		float donePercent = (((float) this.angle) / 360) * 100;
		float progress = (donePercent / 100) * mMaxProgress;
		progressPercent=Math.round(donePercent);
		CALLED_FROM_ANGLE = true;
		setProgress(progress);
	}
	
	/**
	 * Sets the progress.
	 * 
	 * @param progress
	 *            the new progress
	 */
	public void setProgress(float progress) {
		if (this.mMainCurProgress != progress) {
			this.mMainCurProgress = progress;
			if (!CALLED_FROM_ANGLE) {
				float newPercent = (this.mMainCurProgress / this.mMaxProgress) * 100;
				float newAngle = (newPercent / 100) * 360;
				this.setAngle(newAngle);
				progressPercent=newPercent;
			}
			if (mListener!=null) {
				mListener.onProgressChange(this, mMainCurProgress,IS_USEROP);
			}
			IS_USEROP=false;
			CALLED_FROM_ANGLE = false;
		}
	}
	
	/**
	 * 设置进度条最大值
	 * @param value
	 */
	public void setMaxProgress(float value) {
		mMaxProgress = value;
	}
	
	/**
	 * 设置动画完成后，最终需要停在的进度条值
	 * @param value
	 */
	public void setEndProgress(float value) {
		mEndProgress = value;
	}
}
